package handlers

import (
	"encoding/json"
	"fmt"
	"sync/atomic"
	"time"

	"github.com/RuiGuangServer/config"
	"github.com/RuiGuangServer/global"
	"github.com/RuiGuangServer/logs"
	"github.com/RuiGuangServer/utils"
)

type Adsb struct {
	Trkn uint64  `json:"trkn"`  // 唯一航迹号
	Cs   string  `json:"cs"`    // 航班号
	Cs62 string  `json:"cs_62"` // 综合雷达航迹航班号
	DES  string  `json:"DES"`   // 起飞机场
	DEP  string  `json:"DEP"`   // 目的地机场
	Ssr  string  `json:"ssr"`   // 应答机编码
	Addr string  `json:"addr"`  // 24位地址码
	ST   string  `json:"s_t"`   // 数据发送时刻
	Fl   int     `json:"fl"`    // 当前高度
	Lat  float32 `json:"lat"`   // wgs84 纬度
	Long float32 `json:"long"`  // wgs 经度
	Spd  int     `json:"spd"`   // 速度
	Head int     `json:"head"`  // 航向
	Slf  any     `json:"slf"`   // 航空器预设高度
}

func HandleADSB(data []byte, logger *logs.AsyncLogger, dataer *logs.AsyncLogger) {
	dataer.Data("zstd压缩后的数据[ADSB_receive]: %v", data)
	//fmt.Printf("data:%x\n", data)

	adsb, err := parseADSB(data)
	if err != nil {
		logger.Warn("解析ADSB数据失败: %v", err)
		return
	}

	dataer.Data("zstd解压后的数据[ADSB_receive]: %+v", adsb)

	if adsb.Cs == "" {
		logger.Warn("收到航班号为空的ADSB数据")
		return
	}

	// 跳过非本场相关航班
	if adsb.DES != config.Config.AirPort && adsb.DEP != config.Config.AirPort {
		logger.Info("跳过非本场航班: %s (DES:%s, DEP:%s)", adsb.Cs, adsb.DES, adsb.DEP)
		return
	}

	callSign := adsb.Cs
	now := time.Now().Unix()

	// 获取或创建航班状态
	state, exists := global.PlanMap.Load(callSign)
	if !exists {
		state = createNewState(adsb, now)
		global.PlanMap.Store(callSign, state)
		logger.Info("创建新航迹: %s (来源:ADSB)", callSign)
	}

	// 更新航班状态
	updateState(state.(*global.PlanState), adsb, now, logger)

	// 更新最后接收时间
	atomic.StoreInt64(&state.(*global.PlanState).Utime, now)

	logger.Debug("更新ADSB数据: %s", callSign)
}

// 创建新的航班状态
func createNewState(adsb Adsb, now int64) *global.PlanState {
	return &global.PlanState{
		CallSign: adsb.Cs,
		Source:   9,        // ADSB来源标识
		DEP:      adsb.DES, // ADSB中DES是起飞机场
		DES:      adsb.DEP, // ADSB中DEP是目的地机场
		Etot:     getEtot(adsb, now),
		Aldt:     getAldt(adsb, now),
		Utime:    now,
		Stime:    now,
	}
}

// 获取预计起飞时间
func getEtot(adsb Adsb, now int64) int64 {
	if adsb.DES == config.Config.AirPort {
		return now
	}
	return 0
}

// 获取预计降落时间
func getAldt(adsb Adsb, now int64) int64 {
	if adsb.DEP == config.Config.AirPort {
		return now
	}
	return 0
}

// 更新航班状态
func updateState(state *global.PlanState, adsb Adsb, now int64, logger *logs.AsyncLogger) {
	// 更新起飞机场（如果状态中缺失）
	if state.DEP == "" && adsb.DES != "" {
		state.DEP = adsb.DES
		logger.Debug("更新起飞机场: %s -> %s", state.CallSign, adsb.DES)
	}

	// 更新目的地机场（如果状态中缺失）
	if state.DES == "" && adsb.DEP != "" {
		state.DES = adsb.DEP
		logger.Debug("更新目的地机场: %s -> %s", state.CallSign, adsb.DEP)
	}

	// 更新预计起飞时间（如果状态中缺失）
	if state.Etot == 0 && adsb.DES == config.Config.AirPort {
		state.Etot = now
		logger.Debug("更新ETOT: %s -> %d", state.CallSign, now)
	}

	// 更新预计降落时间（如果状态中缺失）
	if state.Aldt == 0 && adsb.DEP == config.Config.AirPort {
		state.Aldt = now
		logger.Debug("更新ALDT: %s -> %d", state.CallSign, now)
	}

	// 确保来源标识正确
	if state.Source != 9 {
		state.Source = 9
	}
}

// 解析ADSB数据
func parseADSB(datas []byte) (Adsb, error) {
	var adsb Adsb
	jsonData, err := utils.ZstdToJson(datas)
	if err != nil {
		return adsb, fmt.Errorf("ZSTD解压失败: %w", err)
	}

	if err := json.Unmarshal(jsonData, &adsb); err != nil {
		return adsb, fmt.Errorf("JSON解析失败: %w", err)
	}

	return adsb, nil
}
